/**
 * Created by jackliu on 15/12/4.
 */
var CONFIG = require('../../common/config');
var CommonUtil = require('../util/CommonUtil');

var redis = require("redis");
var Scripto = require('redis-scripto');
var path = require('path');
var moment = require('moment');

var videoRenderLuaUtil = (function () {

    function videoRenderLuaUtil() {
    }

    // 初始化工具类
    videoRenderLuaUtil.initUtil = function () {
        // 初始化 redis 客户端
        videoRenderLuaUtil.redisClient = redis.createClient({
            host:CONFIG.YJX_VIDEO_RENDER_PROGRESS_REDIS_DOMAIN,
            auth_pass:CONFIG.YJX_VIDEO_RENDER_PROGRESS_REDIS_PASSWORD,
            port:CONFIG.YJX_VIDEO_RENDER_PROGRESS_REDIS_PORT,
            db:CONFIG.YJX_VIDEO_RENDER_PROGRESS_REDIS_DB_NUMBER,
            ttl:CONFIG.YJX_VIDEO_RENDER_PROGRESS_REDIS_TTL
        });
        videoRenderLuaUtil.scriptMgr = new Scripto(videoRenderLuaUtil.redisClient);
        var renderLuaPath = path.resolve(__dirname, '../lua/video_render_lua');
        videoRenderLuaUtil.scriptMgr.loadFromDir(renderLuaPath);
    };

    /**
     * 视频渲染初始化 redis 进度数据
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId         作品唯一标识
     * @param state         作品生成状态标记: 1生成中、2生成失败、3生成成功
     * @param createTimes   作品渲染次数, 失败后重试次数增加
     * @param progress      作品生成进度, 整形 [0, 100]
     * @param outWidth      作品输出视频宽度
     * @param outHeight     作品输出视频高度
     * @param outDuration   作品输出视频时长
     * @param estimate      作品渲染预估时间
     * @param callback      初始化完成回调
     *          error: 初始化脚本失败
     */
    videoRenderLuaUtil.lua_video_init_render = function (docId, state,  createTimes, progress, outWidth, outHeight, outDuration, estimate, callback) {
        var ip = CommonUtil.getLocalIP();
        var duration = 0;
        var startTime = new moment().unix();
        /**
         * --[[
         函数1：lua_video_init_render
         功能：初始化渲染数据。将传入的参数设置到hash对应字段中
         参数：ARGV[1]:doc_id:23
         参数：ARGV[2]:state:1 （状态：1生成中、2生成失败、3生成成功）
         参数：ARGV[3]:ip:"192.168.31.24" （渲染服务器ip）
         参数：ARGV[4]:create_times:1 （渲染次数，失败后重试时此计数增加）
         参数：ARGV[5]:progress:0 （生成进度，整数类型，取值范围：[0,100]）
         参数：ARGV[6]:start_time: 1522032486, 开始时间的时间戳(十位, 秒级)
         参数：ARGV[7]:duration:0 （渲染的持续时间，单位：秒）
         参数：ARGV[8]:out_width:260 （输出视频的宽度）
         参数：ARGV[9]:out_height:360 （输出视频的高度）
         参数：ARGV[10]:out_duration:60 （输出视频的时长）
         参数：ARGV[11]:estimate:60 （预估的渲染时间）
         返回：0表示成功，1表示失败
         --]]*/
        var values = [docId, state, ip, createTimes, progress, startTime, duration, outWidth, outHeight, outDuration, estimate];
        videoRenderLuaUtil.scriptMgr.run('lua_video_init_render', [], values, function (error, result) {
            if (Number(result)) {
                error = error || '初始化渲染出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_init_render err: ' + error);
            }
            return callback(error);
        });
    };

    /**
     * 删除用户作品 redis 中的进度信息
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId     作品唯一标识
     * @param callback  删除回调
     *          err:    删除失败
     */
    videoRenderLuaUtil.lua_video_delete_render = function (docId, callback) {
        /**--[[
         函数10：lua_video_delete_render
         功能：删除render数据
         参数：ARGV[1]:doc_id:23
         返回：0表示成功，1表示失败
         --]]*/
        var values = [docId];
        videoRenderLuaUtil.scriptMgr.run('lua_video_delete_render',  [],values, function (error, result) {
            if (Number(result)) {
                error = error || '删除作品进度出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_delete_render err: ' + error);
            }
            return callback(error);
        });
    };

    /**
     * 设置用户作品排版进度信息
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId         作品唯一标识
     * @param progress      更新的排版进度信息
     * @param callback      回调
     *          err: 设置失败
     */
    videoRenderLuaUtil.lua_video_set_progress = function (docId, progress, callback) {
        /**--[[
         函数2：lua_video_set_progress
         功能：设置progress，并更新duration字段（当前时间减去start_time），当progress为100时将state更新为生成成功
         参数：ARGV[1]:doc_id:23
         参数：ARGV[2]:progress:20 （生成进度，整数类型，取值范围：[0,100]）
         参数：ARGV[3]:current_time: Unix 时间戳, 秒级, 如: 1522032486
         返回：0表示成功，1表示失败
         --]]*/
        var currentTime = new moment().unix();
        var values = [docId, progress, currentTime];
        videoRenderLuaUtil.scriptMgr.run('lua_video_set_progress', [], values,  function (error, result) {
            if (Number(result)) {
                error = error || '设置作品进度出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_set_progress err: ' + error);
            }
            return callback(error, result);
        });
    };

    /**
     * 设置视频排版状态
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId     作品唯一标识
     * @param state     作品生成状态标记: 1生成中、2生成失败、3生成成功
     * @param callback
     *          err:    设置状态失败
     */
    videoRenderLuaUtil.lua_video_set_state = function (docId, state, callback) {
        /**--[[
         函数9：lua_video_set_state
         功能：设置state
         参数：ARGV[1]:doc_id:23
         参数：ARGV[2]:state:1 （状态：1生成中、2生成失败、3生成成功）
         返回：0表示成功，1表示失败
         --]]*/
        var values = [docId, state];
        videoRenderLuaUtil.scriptMgr.run('lua_video_set_state',  [], values, function (error, result) {
            if (Number(result)) {
                error = error || '设置作品排版状态出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_set_state err: ' + error);
            }
            return callback(error);
        });
    };

    /**
     * 获取作品状态
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId     作品唯一标识
     * @param callback  回调
     *          err:    查询失败
     *          state   1生成中、2生成失败、3生成成功
     */
    videoRenderLuaUtil.lua_video_get_state = function (docId, callback) {
        /*--[[
        函数3：lua_video_get_state
        功能：取得state
        参数：ARGV[1]:doc_id:23
        返回：state
        --]]*/
        var values = [docId];
        videoRenderLuaUtil.scriptMgr.run('lua_video_get_state', [], values,  function (error, state) {
            return callback(error, state);
        });
    };


    /**
     * 获取作品进度信息
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId     作品唯一标识
     * @param callback  回调
     *          err:    查询失败
     *          progress:    进度[0,100]
     */
    videoRenderLuaUtil.lua_video_get_progress = function (docId, callback) {
        /**
         --[[
         函数4：lua_video_get_progress
         功能：读取progress
         参数：ARGV[1]:doc_id:23
         返回：progress
         --]]*/
        var values = [docId];
        videoRenderLuaUtil.scriptMgr.run('lua_video_get_progress', [], values,  function (error, progress) {
            return callback(error, progress);
        });
    };


    /**
     * 查询作品是否需要重排版
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId             作品唯一标识
     * @param durationLimit     作品生成时长限制
     * @param createTimesLimit  作品渲染次数限制
     * @param callback          回调
     *          err:    查询失败
     *          result: 0表示不需要处理，1表示需要重新渲染，2表示需要放弃生成
     */
    videoRenderLuaUtil.lua_video_need_rerender = function (docId, durationLimit, createTimesLimit, callback) {
        /*--[[
        函数5：lua_video_need_rerender
        功能：如果state处于“1生成中”，且duration大于duration_limit，且create_times等于create_times_limit，则返回1
             如果state处于“1生成中”，且duration大于duration_limit，且create_times大于create_times_limit，则返回2
             其余case返回0
        参数：ARGV[1]:doc_id:23
        参数：ARGV[2]:duration_limit: 时间限制
        参数：ARGV[3]:create_times_limit: 次数限制
        返回：0表示不需要处理，1表示需要重新渲染，2表示需要放弃生成
        --]]*/
        var currentTime = new moment().unix();
        var values = [docId, durationLimit, createTimesLimit, currentTime];
        videoRenderLuaUtil.scriptMgr.run('lua_video_need_rerender', [], values,  function (error, result) {
            return callback(error, result);
        });
    };


    /**
     * 视频重新排版
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId         作品唯一标识
     * @param callback      回调
     *          err:    重排版失败
     */
    videoRenderLuaUtil.lua_video_rerender = function (docId, callback) {
        var ip = CommonUtil.getLocalIP();
        /**--[[
         函数6：lua_video_rerender
         功能：重新渲染的更新置顶文档的数据。需要：
         将state设置为“1生成中”状态，
         将"create_times"累加1，
         将"progress"设置为0，
         将"start_time"设置为参数"current_time"，
         将"duration"设置为0
         将"ip"设置为参数"ip"，
         参数：ARGV[1]:doc_id:23
         参数：ARGV[2]:ip:"192.168.31.24" （渲染服务器ip）
         参数：ARGV[3]:current_time:"2017-08-01 12:30:08" (当前时间)
         返回：0表示成功，1表示失败
         --]]*/
        var currentTime = new moment().unix();
        var values = [docId, ip, currentTime];
        videoRenderLuaUtil.scriptMgr.run('lua_video_rerender', [], values,  function (error, result) {
            if (Number(result)) {
                error = error || '设置作品排版状态出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_rerender err: ' + error);
            }
            return callback(error);
        });
    };


    /**
     * 放弃作品重排版
     *
     * @author 王俊
     * @date 2018-03-26
     *
     * @param docId         作品唯一标识
     * @param callback      回调
     *          err: 失败
     */
    videoRenderLuaUtil.lua_video_abandon_render = function (docId,  callback) {
        /**--[[
         函数7：lua_video_abandon_rerender
         功能：放弃生成,即将state设置为“2生成失败”
         参数：ARGV[1]:doc_id:23
         返回：0表示成功，1表示失败
         --]]*/
        var values = [docId];
        videoRenderLuaUtil.scriptMgr.run('lua_video_abandon_render', [], values,  function (error, result) {
            if (Number(result)) {
                error = error || '设置作品排版状态出错';
            }
            if (error) {
                console.log('commonUtils/util/videoRenderLuaUtil.lua_video_abandon_rerender err: ' + error);
            }
            return callback(error, result);
        });
    };

    /**
     * 获取生成中的文档 id 集合
     * @param callback  回调
     *          err:    查询失败
     *          docIds: 作品 id 集合
     */
    videoRenderLuaUtil.lua_video_get_docs_under_processing = function (callback) {
        /**--[[
         函数8：lua_video_get_docs_under_processing
         功能：获取state处于“1生成中”状态的文档的id的集合
         返回：文档id的集合，半角逗号分隔，例如："1,2,3,4"
         --]]*/
        videoRenderLuaUtil.scriptMgr.run('lua_video_get_docs_under_processing', [], [], function (error, result) {
            return callback(error, result);
        });
    };

    /**
     * 获取redis 中的渲染进度信息
     *
     * @param docId     作品唯一标识
     * @param callback  回调
     *          err:    查询失败
     *          data: {
     *              duration: 当前已生成时长
     *              progress: 当前进度信息
     *              estimate: 预估时间
     *          }
     */
    videoRenderLuaUtil.lua_video_get_duration = function (docId, callback) {
        /*--[[
            函数11：lua_video_get_duration
            功能：取得某个文档生成时间duration、生成进度progress、预估渲染时间estimate
            参数：ARGV[1]:doc_id:23
            参数：ARGV[1]:current_time: 当前时间戳
            返回：按以下顺序返回数组：
                    duration
                    progress
                    estimate
        --]]*/
        var currentTime = new moment().unix();
        var values = [docId, currentTime];
        videoRenderLuaUtil.scriptMgr.run('lua_video_get_duration', [], values, function (error, result) {
            if(error || !result || result.length <=0) {
                return callback(error || '查询进度失败', null);
            }
            var obj = {
                duration : Number(result[0]),
                progress : Number(result[1]),
                estimate : Number(result[2])
            };
            console.log('lua_video_get_duration: ' + JSON.stringify(result));
            return callback(error, obj);
        });
    };

    /**
     * 获取设置进度的 lua 脚本的 sha 值
     * @param callback 回调
     *          err: 查询失败
     *          sha: sha 值
     */
    videoRenderLuaUtil.get_lua_set_progress_sha = function (callback) {
        var scriptShas =  videoRenderLuaUtil.scriptMgr['_scriptShas'];
        var sha = scriptShas['lua_video_set_progress'];
        var err = !sha ? '获取 sha 失败' : null;
        return callback(err,sha);
    };


    return videoRenderLuaUtil;

})();
// 初始化工具类
videoRenderLuaUtil.initUtil();
// videoRenderLuaUtil.lua_video_get_docs_under_processing(function(err, result){
//    console.log(err + result);
// });

module.exports = videoRenderLuaUtil;

